Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Commit 4238b9daf609eab5589c7743d7dc3c7af58e4e2d


Parents : 67ee8cc
Author : Ivan <ivan@quad4.io>
Signature : Signature validation error
Date : 2026-05-03T00:36:39-05:00

feat(workflows): add SLSA provenance generation for Android APK and Flatpak artifacts

Changes

2 files changed, 125 insertions(+), 2 deletions(-)


Diff

diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml
index 969c85b4..6dcff240 100644
--- a/.github/workflows/build-release.yml
+++ b/.github/workflows/build-release.yml
@@ -1,6 +1,6 @@
# Single tagged-release pipeline: Linux release assets, Windows + macOS Electron
# builds, Flatpak, Android APKs (dev/master track tags via android-apk-tag.yml), SLSA
-# provenance (generic generator), optional cosign bundles, and one draft GitHub release.
+# provenance (generic generator: Linux, desktop, optional Android+Flatpak), optional cosign bundles, and one draft GitHub release.
# One workflow run per tag keeps the release graph immutable.
#
# Pinned first-party actions (bump tag and SHA together when upgrading):
@@ -495,6 +495,50 @@ jobs:
upload-assets: false
provenance-name: meshchatx-desktop-${{ github.ref_name }}.intoto.jsonl
+ collect-android-flatpak-slsa-subjects:
+ name: SLSA subjects (Android APK + Flatpak)
+ needs: [android-release, flatpak]
+ if: startsWith(github.ref, 'refs/tags/')
+ runs-on: ubuntu-latest
+ outputs:
+ hashes: ${{ steps.hash.outputs.hashes }}
+ has_subjects: ${{ steps.hash.outputs.has_subjects }}
+ steps:
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
+
+ - name: Download Android APK bundle
+ continue-on-error: true
+ uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
+ with:
+ name: meshchatx-android-apks-${{ github.ref_name }}-${{ github.run_id }}
+ path: dl/android
+
+ - name: Download Flatpak artifact
+ continue-on-error: true
+ uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
+ with:
+ name: meshchatx-linux-flatpak-${{ github.ref_name }}-${{ github.run_id }}
+ path: dl/flatpak
+
+ - name: Hash Android / Flatpak artifacts
+ id: hash
+ run: bash scripts/ci/github-slsa-hashes-apk-flatpak.sh dl/android dl/flatpak
+
+ slsa-provenance-android-flatpak:
+ name: SLSA provenance (Android + Flatpak)
+ needs: [collect-android-flatpak-slsa-subjects]
+ if: ${{ startsWith(github.ref, 'refs/tags/') && needs.collect-android-flatpak-slsa-subjects.outputs.has_subjects == 'true' }}
+ permissions:
+ id-token: write
+ contents: write
+ actions: read
+ uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
+ with:
+ base64-subjects: ${{ needs.collect-android-flatpak-slsa-subjects.outputs.hashes }}
+ upload-assets: false
+ provenance-name: meshchatx-android-flatpak-${{ github.ref_name }}.intoto.jsonl
+
draft-github-release:
name: Draft GitHub release (all assets + SLSA)
needs:
@@ -504,7 +548,22 @@ jobs:
- slsa-provenance-desktop
- flatpak
- android-release
- if: startsWith(github.ref, 'refs/tags/')
+ - collect-android-flatpak-slsa-subjects
+ - slsa-provenance-android-flatpak
+ if: >-
+ always() &&
+ !cancelled() &&
+ startsWith(github.ref, 'refs/tags/') &&
+ needs.linux-release.result == 'success' &&
+ needs.slsa-provenance-linux.result == 'success' &&
+ needs.build-release.result == 'success' &&
+ needs.collect-desktop-slsa-subjects.result == 'success' &&
+ needs.slsa-provenance-desktop.result == 'success' &&
+ needs.flatpak.result == 'success' &&
+ needs.android-release.result == 'success' &&
+ needs.collect-android-flatpak-slsa-subjects.result == 'success' &&
+ (needs.slsa-provenance-android-flatpak.result == 'success' ||
+ needs.slsa-provenance-android-flatpak.result == 'skipped')
runs-on: ubuntu-latest
timeout-minutes: 45
permissions:
@@ -560,6 +619,13 @@ jobs:
name: ${{ needs.slsa-provenance-desktop.outputs.provenance-name }}
path: upload
+ - name: Download SLSA provenance (Android + Flatpak)
+ continue-on-error: true
+ uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0
+ with:
+ name: meshchatx-android-flatpak-${{ github.ref_name }}.intoto.jsonl
+ path: upload
+
- name: SLSA cosign bundles (desktop only)
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}

diff --git a/scripts/ci/github-slsa-hashes-apk-flatpak.sh b/scripts/ci/github-slsa-hashes-apk-flatpak.sh
new file mode 100644
index 00000000..60c65dda
--- /dev/null
+++ b/scripts/ci/github-slsa-hashes-apk-flatpak.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+# Emit base64-encoded sha256sum lines for *.apk, *.flatpak, and *.flatpakref under
+# given roots (SLSA generic generator input). Writes hashes= and has_subjects= to
+# GITHUB_OUTPUT when set.
+set -euo pipefail
+
+if [ "$#" -lt 1 ]; then
+ echo "usage: $0 <root> [root...]" >&2
+ exit 1
+fi
+
+roots=()
+for d in "$@"; do
+ [ -d "$d" ] && roots+=("$d")
+done
+
+write_empty() {
+ if [ -n "${GITHUB_OUTPUT:-}" ]; then
+ {
+ echo "hashes="
+ echo "has_subjects=false"
+ } >>"$GITHUB_OUTPUT"
+ else
+ printf '%s\n' ""
+ fi
+}
+
+if [ "${#roots[@]}" -eq 0 ]; then
+ echo "No existing directories in: $* (no APK/Flatpak subjects)" >&2
+ write_empty
+ exit 0
+fi
+
+tmp="$(mktemp)"
+trap 'rm -f "$tmp"' EXIT
+
+find "${roots[@]}" -type f \( \
+ -name '*.apk' -o -name '*.flatpak' -o -name '*.flatpakref' \
+ \) ! -path '*/.*' -print0 \
+ | LC_ALL=C sort -z \
+ | xargs -0r sha256sum >"$tmp"
+
+if [ ! -s "$tmp" ]; then
+ echo "No .apk / .flatpak / .flatpakref under: ${roots[*]}" >&2
+ write_empty
+ exit 0
+fi
+
+b64="$(base64 -w0 <"$tmp")"
+if [ -n "${GITHUB_OUTPUT:-}" ]; then
+ {
+ echo "hashes=${b64}"
+ echo "has_subjects=true"
+ } >>"$GITHUB_OUTPUT"
+else
+ printf '%s\n' "$b64"
+fi


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────